#include "serialdevice.h"
#include "dmcomm.h"

#include <thread>

std::vector<DevInfo> SerialDevice::getDeviceInfo()
{
    std::vector<DevInfo> vect;

    const auto ports = itas109::CSerialPortInfo::availablePortInfos();
    DevInfo info;
    info.type = DevType::Serial;
    info.desc = std::to_string(itas109::BaudRate115200);
    for (const auto &port : ports) {
        info.path = port.portName;
        info.id = port.portName;
        vect.push_back(info);
    }
    return vect;
}

SerialDevice::SerialDevice(const std::string &com)
    : DeviceInterface{com}
    , m_serial{std::make_unique<itas109::CSerialPort>()}

{
    m_serial->init(com.c_str(),
                   itas109::BaudRate115200,
                   itas109::ParityNone,
                   itas109::DataBits8,
                   itas109::StopOne,
                   itas109::FlowNone,
                   READ_BUFFER_SIZE);
    if (!m_serial->open()) {
        error(DmCommError::OpenError);
    }
}

SerialDevice::~SerialDevice()
{
    close();
}

void SerialDevice::write(const std::vector<uint8_t> &data, const uint16_t &timeout)
{
    if (!m_serial->isOpen() || data.empty()) {
        return;
    }

    auto res = m_serial->writeData(data.data(), data.size());
    if (-1 == res) {
        error(DmCommError::WriteError);
        return;
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(2 + timeout));

    m_data.clear();
    res = m_serial->readAllData(m_data.data());
    if (-1 == res) {
        error(DmCommError::ReadError);
    }
    else if (0 == res) {
        return;
    }

    recv(m_data);
    m_data.clear();
}

bool SerialDevice::isOpen() const
{
    return m_serial->isOpen();
}

std::string SerialDevice::getDescription() const
{
    return "";
}

void SerialDevice::close()
{
    if (m_serial->isOpen()) {
        m_serial->close();
    }
}
